source: GTP/trunk/App/Demos/Illum/Standalone/HierRayEngine [DirectX]/HREEffect.cpp @ 1481

Revision 1481, 28.2 KB checked in by szirmay, 18 years ago (diff)
Line 
1#include "dxstdafx.h"
2#include ".\hreeffect.h"
3
4struct ProcessedTriangle                        //< a vertex encoding a triangle
5{
6        Vector sphereCentre;                    //< endclosig sphere centre                                                     : POSITION.xyz
7        float radius;                                   //< endclosing sphere radius                                            : POSITION.w
8        Vector planePos;                                //< triangle plane point nearest to origin                      : NORMAL
9        Vector inverseVertexMatrix[3];  //< Cartesian-to-barycentric transformation matrix      : TEXCOORD0-2
10        Vector normals[3];                              //< model normals at triangle vertices                          : TEXCOORD3-5
11        Vector tex[3];                                  //< model texture coords at triangle vertices           : TEXCOORD6-8
12};
13
14//! D3D vector-matrix multiplication
15D3DVECTOR operator *(const D3DVECTOR& v, const D3DMATRIX& m)
16{
17        D3DVECTOR r;
18        r.x = v.x * m._11 + v.y * m._21 + v.z * m._31 + m._41;
19        r.y = v.x * m._12 + v.y * m._22 + v.z * m._32 + m._42;
20        r.z = v.x * m._13 + v.y * m._23 + v.z * m._33 + m._43;
21        float h = v.x * m._14 + v.y * m._24 + v.z * m._34 + m._44;
22        if(h > 0.00001f || h < 0.00001f)
23        {
24                r.x /= h;
25                r.y /= h;
26                r.z /= h;
27        }
28        return r;
29}
30
31//! method name strings to be displayed on screen
32const wchar_t* HREEffect::Method::methodNames[10] =
33{
34        L"Ray Engine",
35        L"_",
36        L"_",
37        L"_"
38        , NULL, NULL, NULL, NULL, NULL, NULL
39};
40
41//! method constants
42const HREEffect::Method HREEffect::Method::RAYENGINE(0);
43const HREEffect::Method HREEffect::Method::LAST(1);
44
45HREEffect::HREEffect(LPDIRECT3DDEVICE9 device)
46:method(Method::RAYENGINE)
47{
48        this->device = device;
49
50        //first person camera allows more freedom of movement
51        camera = new CFirstPersonCamera();
52        lightCamera = new CFirstPersonCamera();
53
54        HRESULT hr;
55        DWORD effectCompileFlag=0;
56       
57        LPD3DXBUFFER compilationErrors;
58        if(FAILED(
59                hr =
60                        D3DXCreateEffectFromFile(
61                                device,
62                                L"rayEngine.fx",
63                                NULL,
64                                NULL,
65                                0,
66                                NULL,
67                                &effect,
68                                &compilationErrors) )){
69                MessageBoxA( NULL, (LPSTR)compilationErrors->GetBufferPointer(), "Failed to load effect file!", MB_OK);
70                exit(-1);
71        }
72
73        //store buffers so we can reset them after rendering to texture render targets
74        device->GetRenderTarget(0, &frameColorBuffer);
75        device->GetDepthStencilSurface(&frameDepthStencilBuffer);
76
77        camera->SetViewParams( &D3DXVECTOR3(0.0f, 0.0f, 4.0f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f));
78        D3DSURFACE_DESC fbdesc;
79        frameColorBuffer->GetDesc(&fbdesc);
80        camera->SetProjParams( D3DX_PI/2, (float)fbdesc.Width / fbdesc.Height, 0.1f, 300.0f );
81
82        hr = D3DXCreateCubeTextureFromFile(device, L"media//uffizi_lowrange.dds", &environmentCubeTexture);
83
84        hr=device->CreateTexture(RAY_TABLE_WIDTH / 16,RAY_TABLE_HEIGHT / 16,1,D3DUSAGE_RENDERTARGET,D3DFMT_A32B32G32R32F,D3DPOOL_DEFAULT,&conePeakTexture,NULL);
85        hr=conePeakTexture->GetSurfaceLevel(0,&conePeakSurface);
86
87        hr=device->CreateTexture(RAY_TABLE_WIDTH / 16,RAY_TABLE_HEIGHT / 16,1,0,D3DFMT_A32B32G32R32F,D3DPOOL_SYSTEMMEM,&conePeakTextureMem,NULL);
88        hr=conePeakTextureMem->GetSurfaceLevel(0,&conePeakSurfaceMem);
89
90        hr=device->CreateTexture(RAY_TABLE_WIDTH / 16,RAY_TABLE_HEIGHT / 16,1,D3DUSAGE_RENDERTARGET,D3DFMT_A32B32G32R32F,D3DPOOL_DEFAULT,&coneDirTexture,NULL);
91        hr=coneDirTexture->GetSurfaceLevel(0,&coneDirSurface);
92
93        hr=device->CreateTexture(RAY_TABLE_WIDTH / 16,RAY_TABLE_HEIGHT / 16,1,0,D3DFMT_A32B32G32R32F,D3DPOOL_SYSTEMMEM,&coneDirTextureMem,NULL);
94        hr=coneDirTextureMem->GetSurfaceLevel(0,&coneDirSurfaceMem);
95
96        hr=device->CreateTexture(RAY_TABLE_WIDTH,RAY_TABLE_HEIGHT,1,D3DUSAGE_RENDERTARGET,RAY_ORIGIN_COLOR_FORMAT,D3DPOOL_DEFAULT,&rayOriginTableTexture,NULL);
97        hr=rayOriginTableTexture->GetSurfaceLevel(0,&rayOriginTableSurface);
98        hr=device->CreateTexture(RAY_TABLE_WIDTH,RAY_TABLE_HEIGHT,1,D3DUSAGE_RENDERTARGET,RAY_DIR_COLOR_FORMAT,D3DPOOL_DEFAULT,&rayDirTableTexture,NULL);
99        hr=rayDirTableTexture->GetSurfaceLevel(0,&rayDirTableSurface);
100
101        hr=device->CreateTexture(RAY_TABLE_WIDTH,RAY_TABLE_HEIGHT,1,D3DUSAGE_RENDERTARGET,RAY_ORIGIN_COLOR_FORMAT,D3DPOOL_DEFAULT,&rayOriginTableTexture2,NULL);
102        hr=rayOriginTableTexture2->GetSurfaceLevel(0,&rayOriginTableSurface2);
103        hr=device->CreateTexture(RAY_TABLE_WIDTH,RAY_TABLE_HEIGHT,1,D3DUSAGE_RENDERTARGET,RAY_DIR_COLOR_FORMAT,D3DPOOL_DEFAULT,&rayDirTableTexture2,NULL);
104        hr=rayDirTableTexture2->GetSurfaceLevel(0,&rayDirTableSurface2);
105
106        device->CreateDepthStencilSurface(RAY_TABLE_WIDTH / 16,RAY_TABLE_HEIGHT / 16,DEPTH_FORMAT,D3DMULTISAMPLE_NONE,0,false,&coneStencil,NULL);
107
108        device->CreateDepthStencilSurface(RAY_TABLE_WIDTH,RAY_TABLE_HEIGHT,DEPTH_FORMAT,D3DMULTISAMPLE_NONE,0,false,&depthSurface,NULL);
109
110        D3DVERTEXELEMENT9 trianglePrimitiveDeclElements[] =
111        {
112                {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION , 0},
113                {0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL , 0},
114                {0, 28, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 0},
115                {0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 1},
116                {0, 52, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 2},
117                {0, 64, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 3},
118                {0, 76, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 4},
119                {0, 88, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 5},
120                {0, 100, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 6},
121                {0, 112, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 7},
122                {0, 124, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 8},
123                D3DDECL_END()
124        };
125        hr = device->CreateVertexDeclaration(trianglePrimitiveDeclElements, &trianglePrimitiveDeclaration);
126
127        //load empty texture
128        D3DXCreateTextureFromFile(device, L"media\\empty.bmp", &emptyTexture);
129
130        //set up a scene
131        loadMesh( L"media\\pillow.x" );
132        loadMesh( L"media\\torus.x" );
133
134        Entity e1;
135        e1.owner = this;
136        e1.mesh = meshes.at(0);
137        D3DXMatrixIdentity(&e1.modelWorldTransform);
138        D3DXMatrixIdentity(&e1.inverseTransposedModelWorldTransform);
139        entities.push_back(e1);
140
141        Entity e2;
142        e2.owner = this;
143        e2.mesh = meshes.at(1);
144        D3DXMatrixIdentity(&e2.modelWorldTransform);
145        D3DXMatrixTranslation(&e2.modelWorldTransform, 5.0, 0.0, 0.0);
146
147        D3DXMatrixInverse(  &e2.inverseTransposedModelWorldTransform, NULL,
148                                                &e2.modelWorldTransform);
149        D3DXMatrixTranspose( &e2.inverseTransposedModelWorldTransform, &e2.inverseTransposedModelWorldTransform);
150        entities.push_back(e2);
151
152}
153
154HREEffect::~HREEffect(void)
155{
156        rayOriginTableSurface->Release();
157         rayOriginTableTexture->Release();
158         rayDirTableSurface->Release();
159         rayDirTableTexture->Release();
160         depthSurface->Release();
161         rayOriginTableSurface2->Release();
162         rayOriginTableTexture2->Release();
163         rayDirTableSurface2->Release();
164         rayDirTableTexture2->Release();
165         environmentCubeTexture->Release();
166         conePeakSurface->Release();
167         conePeakTexture->Release();
168         coneDirSurface->Release();
169         coneDirTexture->Release();
170
171        emptyTexture->Release();
172        releaseTextures();
173        releaseMeshes();
174        releaseEntities();
175
176        frameColorBuffer->Release();
177        frameDepthStencilBuffer->Release();
178
179        effect->Release();
180        delete camera;
181        delete lightCamera;
182}
183
184
185void HREEffect::loadMesh(LPCWSTR fileName)
186{
187        Mesh*           renderMesh = new Mesh();
188
189        if(S_OK !=
190                D3DXLoadMeshFromX(      fileName,
191                                                        D3DXMESH_MANAGED,
192                            device,
193                                                        NULL,
194                                                        &renderMesh->materialBuffer,
195                                                        NULL,
196                                                        (DWORD*)&renderMesh->nSubsets,
197                                                        &renderMesh->mesh))
198        {
199                 MessageBox(NULL, fileName, L"Could not load mesh file!", MB_OK);
200                 return;
201        }
202        //convert mesh into a vertex format using a position, a normal and a texture register
203        //this is the only data our vertex shaders will require
204        renderMesh->setVertexFormat(D3DFVF_XYZ |
205                                                D3DFVF_NORMAL, device);
206
207        //extract the D3DXMATERIAL* pointer from the generic D3DXBUFFER
208        renderMesh->materials = (D3DXMATERIAL*)renderMesh->materialBuffer->GetBufferPointer();
209
210        //for every material, load the specified texture
211        renderMesh->textures = new LPDIRECT3DTEXTURE9[renderMesh->nSubsets];
212        for(unsigned int i=0; i<renderMesh->nSubsets; i++)
213        {
214                wchar_t* wideTextureFileName = NULL;
215                if(renderMesh->materials[i].pTextureFilename)
216                {
217                        wideTextureFileName = new wchar_t[MultiByteToWideChar(CP_ACP, 0, renderMesh->materials[i].pTextureFilename, -1, NULL, 0)];
218                        MultiByteToWideChar(CP_ACP, 0, renderMesh->materials[i].pTextureFilename, -1, wideTextureFileName, 511);
219                }
220                renderMesh->textures[i] = loadTexture( wideTextureFileName );
221                if(wideTextureFileName)
222                        delete wideTextureFileName;
223        }
224
225        {
226                ProcessedTriangle *tris;
227                device->CreateVertexBuffer(renderMesh->mesh->GetNumFaces() * sizeof(ProcessedTriangle),
228                        D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT,
229                        &renderMesh->primitiveVertexBuffer, NULL);
230                renderMesh->primitiveVertexBuffer->Lock(0, 0, (void**)&tris, 0);
231
232                LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
233                renderMesh->mesh->GetVertexBuffer(&vertexBuffer);
234                unsigned int nVertices = renderMesh->mesh->GetNumVertices();
235                unsigned int nFaces = renderMesh->mesh->GetNumFaces();
236                struct D3DVERTEX{
237                        D3DXVECTOR3 pos;
238                        D3DXVECTOR3 normal;
239                };
240                D3DVERTEX* vertices;
241                vertexBuffer->Lock(0, 0, (void**)&vertices, 0);
242                LPDIRECT3DINDEXBUFFER9 indexBuffer;
243                renderMesh->mesh->GetIndexBuffer(&indexBuffer);
244                unsigned short* indices;
245                indexBuffer->Lock(0, 0, (void**)&indices, 0);
246
247                for(int i=0; i < nFaces; i++)
248                {
249                        Vector A[3];
250                        A[0] = Vector(vertices[indices[i*3]].pos);
251                        A[1] = Vector(vertices[indices[i*3+1]].pos);
252                        A[2] = Vector(vertices[indices[i*3+2]].pos);
253                        float           t4 = A[0][0]*A[1][1];
254                        float       t6 = A[0][0]*A[1][2];
255                        float       t8 = A[0][1]*A[1][0];
256                        float       t10 = A[0][2]*A[1][0];
257                        float       t12 = A[0][1]*A[2][0];
258                        float       t14 = A[0][2]*A[2][0];
259                        float       t17 = 1/(t4*A[2][2]-t6*A[2][1]-t8*A[2][2]+t10*A[2][1]+t12*A[1][2]-t14*A[1][1]);
260               
261        //              if(_isnan (t17) )
262        //          AfxMessageBox("mtx inversion gbz");
263                        Vector* m = tris[i].inverseVertexMatrix;
264                                       
265                        m[0][0] = (A[1][1]*A[2][2]-A[1][2]*A[2][1])*t17;
266                        m[1][0] = -(A[0][1]*A[2][2]-A[0][2]*A[2][1])*t17;
267                        m[2][0] = -(-A[0][1]*A[1][2]+A[0][2]*A[1][1])*t17;
268                        m[0][1] = -(A[1][0]*A[2][2]-A[1][2]*A[2][0])*t17;
269                        m[1][1] = (A[0][0]*A[2][2]-t14)*t17;
270                        m[2][1] = -(t6-t10)*t17;
271                        m[0][2] = -(-A[1][0]*A[2][1]+A[1][1]*A[2][0])*t17;
272                        m[1][2] = -(A[0][0]*A[2][1]-t12)*t17;
273                        m[2][2] = (t4-t8)*t17;
274                       
275                        Vector c = A[0] - A[1];
276                        Vector b = A[0] - A[2];
277                        Vector a = A[1] - A[2];
278                        Vector trinormal = a && b;
279                        trinormal.normalize();
280                        float s = trinormal * A[0];
281                        Vector triPlanePos = trinormal * s;
282                        tris[i].planePos = triPlanePos;
283                        tris[i].normals[0] = Vector(vertices[indices[i*3]].normal);
284                        tris[i].normals[1] = Vector(vertices[indices[i*3+1]].normal);
285                        tris[i].normals[2] = Vector(vertices[indices[i*3+2]].normal);
286                        float a2 = a.norm2();
287                        float b2 = b.norm2();
288                        float c2 = c.norm2();
289
290                        float wa = a2 * (b2 + c2 - a2);
291                        float wb = b2 * (a2 + c2 - b2);
292                        float wc = c2 * (a2 + b2 - c2);
293                        float wsum = wa+wb+wc;
294                        Vector spcen = A[0] * (wa / wsum);
295                        spcen += A[1] * (wb / wsum);
296                        spcen += A[2] * (wc / wsum);
297
298                        Vector cTriNormal = Vector(
299                                tris[i].inverseVertexMatrix[0].x + tris[i].inverseVertexMatrix[1].x + tris[i].inverseVertexMatrix[2].x,
300                                tris[i].inverseVertexMatrix[0].y + tris[i].inverseVertexMatrix[1].y + tris[i].inverseVertexMatrix[2].y,
301                                tris[i].inverseVertexMatrix[0].z + tris[i].inverseVertexMatrix[1].z + tris[i].inverseVertexMatrix[2].z
302                                );
303                        cTriNormal *= 1.0 / cTriNormal.norm2();
304
305                        tris[i].sphereCentre = spcen;
306                        tris[i].radius = (spcen - A[0]).norm();
307
308                }
309                renderMesh->primitiveVertexBuffer->Unlock();
310
311                vertexBuffer->Unlock();
312                indexBuffer->Unlock();
313                vertexBuffer->Release();
314                indexBuffer->Release();
315        }
316
317        //store completed mesh
318        meshes.push_back(renderMesh);
319}
320
321LPDIRECT3DTEXTURE9 HREEffect::loadTexture(LPCWSTR fileName)
322{
323        if(fileName == NULL || wcscmp(fileName, L"") == 0)
324                return NULL;
325        wchar_t* mediaFileName = new wchar_t[wcslen(fileName) + 64];
326        //we assume the x file was in folder .\media
327        wcscpy(mediaFileName, L"media\\");
328        wcscat(mediaFileName, fileName);
329        LPDIRECT3DTEXTURE9 tex;
330
331        D3DXIMAGE_INFO bobo;
332        if(S_OK !=
333                D3DXCreateTextureFromFileEx(device, mediaFileName, D3DX_DEFAULT, D3DX_DEFAULT, 1, 0,
334                D3DFMT_FROM_FILE, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, &bobo, NULL, &tex
335                ))
336        {
337                 MessageBox(NULL, mediaFileName, L"Could not load texture file!", MB_OK);
338                 return NULL;
339        }
340       
341        materialTextures.push_back(tex);
342        return tex;
343}
344
345void HREEffect::releaseTextures()
346{
347        std::vector<LPDIRECT3DTEXTURE9>::iterator i = materialTextures.begin();
348        while(i != materialTextures.end())
349        {
350                (*i)->Release();
351                i++;
352        }
353}
354
355void HREEffect::releaseMeshes()
356{
357        std::vector<HREEffect::Mesh*>::iterator i = meshes.begin();
358        while(i != meshes.end())
359        {
360                (*i)->mesh->Release();
361                (*i)->materialBuffer->Release();
362                (*i)->primitiveVertexBuffer->Release();
363                delete *i;
364                i++;
365        }
366}
367
368void HREEffect::releaseEntities()
369{
370        std::vector<HREEffect::Entity>::iterator entityIterator = entities.begin();
371        while(entityIterator != entities.end())
372        {
373                entityIterator++;
374        }       
375}
376
377LRESULT HREEffect::handleMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
378{
379        if(parameters->Get(bMoveLight))
380                return lightCamera->HandleMessages(hWnd, uMsg, wParam, lParam);
381        else
382                return camera->HandleMessages(hWnd, uMsg, wParam, lParam);
383}
384
385void HREEffect::addUiParameters(Parameters* parameters)
386{
387        HREEffect::parameters = parameters;
388        parameters->Add( bLookFromLight, "Look from light", 1);
389        parameters->Add( bMoveLight, "Move light", 1);
390        parameters->Add( bDots, "Entry points", 1);
391        parameters->Add( bTurbo, "Turbo", 1);
392        parameters->Add( fRayPathLength, "Iterations", 10, 'V', 'B', convert10);
393}
394
395Parameters*     HREEffect::parameters = NULL;
396
397HRESULT HREEffect::Mesh::setVertexFormat(DWORD fvf, LPDIRECT3DDEVICE9 device)
398{
399        LPD3DXMESH tempMesh;
400
401        //clone the mesh to the appropriate format
402    HRESULT hr = mesh->CloneMeshFVF( mesh->GetOptions(),
403                                  fvf ,
404                                  device, &tempMesh );
405        if(hr == S_OK)
406        {
407                DWORD* padj = new DWORD[mesh->GetNumFaces() * 3];
408                mesh->GenerateAdjacency(0.00001f, padj);
409                delete padj;
410                //forget he old mesh
411                mesh->Release();
412                //use the cloned mesh
413                mesh = tempMesh;
414        }
415        return hr;
416}
417
418void HREEffect::move(float fElapsedTime)
419{
420        //apply some rotation to one of the entities
421        D3DXMATRIX rot;
422        D3DXMatrixRotationY(&rot, fElapsedTime * 1.0);
423        D3DXMatrixMultiply( &entities.at(0).modelWorldTransform,
424                                                &rot,
425                                                &entities.at(0).modelWorldTransform);
426        D3DXMatrixInverse(  &entities.at(0).inverseTransposedModelWorldTransform, NULL,
427                                                &entities.at(0).modelWorldTransform);
428        D3DXMatrixTranspose( &entities.at(0).inverseTransposedModelWorldTransform, &entities.at(0).inverseTransposedModelWorldTransform);
429
430        if(parameters->Get(bTurbo))
431        {
432                camera->FrameMove(fElapsedTime * 10.0f);
433                lightCamera->FrameMove(fElapsedTime * 10.0f);
434        }
435        else
436        {
437                camera->FrameMove(fElapsedTime);
438                lightCamera->FrameMove(fElapsedTime);
439        }
440}
441
442void HREEffect::render()
443{
444        HRESULT hr;     UINT nPasses=1;
445        D3DXIMAGE_FILEFORMAT fileFormat=D3DXIFF_HDR;
446
447        device->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
448                                                D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
449
450        D3DXMATRIX worldToScreen = *camera->GetViewMatrix() * *camera->GetProjMatrix();
451        Vector eyePos = *camera->GetEyePt();
452
453        hr=device->SetRenderTarget(0,rayOriginTableSurface);
454        hr=device->SetRenderTarget(1,rayDirTableSurface);
455
456        hr=device->SetDepthStencilSurface(depthSurface);
457
458        device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
459        device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
460        device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
461        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
462        device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
463        device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
464        device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
465        device->SetRenderState(D3DRS_STENCILREF, 0x1);
466        hr=device->SetRenderState(D3DRS_STENCILMASK, 0x1);
467        hr=device->SetRenderState(D3DRS_STENCILWRITEMASK, 0x01);
468
469        device->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,
470                        D3DCOLOR_ARGB(1,0,0,0), 1.0f, 0 );
471
472        // Render initial rays
473        if( SUCCEEDED( device->BeginScene() ) ){
474                if( effect != NULL ){
475                        D3DXHANDLE hTechnique = effect->GetTechniqueByName((LPSTR)"RenderPrimaryRayArray");
476                        if(hTechnique==NULL){
477                                return;
478                        }
479                        effect->SetTechnique( hTechnique );
480                       
481                        effect->Begin( &nPasses, 0 );
482                        for(UINT j=0;j<nPasses;j++){
483                                effect->BeginPass(j);
484                                hr = effect->SetFloatArray("EyePos", (float*)&eyePos, 3);
485                                hr = effect->SetFloat("RefractionIndex", 0.9);
486
487                                //loop through all entities, all mesh subsets, set proper transformations
488                                std::vector<HREEffect::Entity>::iterator entityIterator = entities.begin();
489                                while(entityIterator != entities.end())
490                                {
491                                        hr=effect->SetMatrix("WorldViewProj", &(entityIterator->modelWorldTransform * *camera->GetViewMatrix() * *camera->GetProjMatrix() ));
492                                        hr=effect->SetMatrix("World", &entityIterator->modelWorldTransform);
493                                        hr=effect->SetMatrix("WorldIT", &entityIterator->inverseTransposedModelWorldTransform);
494                                        hr=effect->SetFloat("colOrder", 10.0f);
495                                        effect->CommitChanges();
496                                        unsigned int nSubsets = entityIterator->mesh->nSubsets;
497                                        for(int i = 0; i< nSubsets; i++)
498                                        {
499                                                entityIterator->mesh->mesh->DrawSubset(i);
500                                        }
501                                        entityIterator++;
502                                }
503                                effect->EndPass();
504                        }
505                        effect->End();
506                }
507                device->EndScene();
508        }
509
510        //ray cast
511        device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
512        device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
513        device->SetRenderState(D3DRS_STENCILREF, 0xff);
514
515        device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
516        device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
517        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
518        float pointSize = 16.0f;
519        hr = device->SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&pointSize));
520        hr = device->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&pointSize));
521
522        unsigned int nIter = parameters->Get(fRayPathLength);
523
524        for(int rd =0; rd < nIter; rd++)
525        {
526                device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
527                device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
528                hr=device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
529                hr=device->SetRenderTarget(1, coneDirSurface);
530                hr=device->SetRenderTarget(0, conePeakSurface);
531                hr=device->SetDepthStencilSurface(NULL);
532
533                if( SUCCEEDED( device->BeginScene() ) ){
534                        if( effect != NULL ){
535                                D3DXHANDLE hTechnique = effect->GetTechniqueByName((LPSTR)"ComputeCones");
536                                if(hTechnique==NULL){
537                                        return ;
538                                }
539                                effect->SetTechnique( hTechnique );
540                               
541                                effect->Begin( &nPasses, 0 );
542                                for(UINT j=0;j<nPasses;j++){
543                                        effect->BeginPass(j);
544                                        hr=effect->SetTexture("rayOriginTable", rayOriginTableTexture);
545                                        hr=effect->SetTexture("rayDirTable", rayDirTableTexture);
546                                        effect->CommitChanges();
547                                        drawFullScreenQuad(device);
548                                        effect->EndPass();
549                                }
550                                effect->End();
551                        }
552                        device->EndScene();
553                }
554
555/*              device->SetRenderTarget(1, NULL);
556                device->SetRenderTarget(0, rayOriginTableSurface2);
557                device->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 1.0f, 0 );
558
559                if( SUCCEEDED( device->BeginScene() ) ){
560                        if(effect != NULL ){
561                                D3DXHANDLE hTechnique = effect->GetTechniqueByName((LPSTR)"ConeChecker");
562                                if(hTechnique==NULL){
563                                        return;
564                                }
565                                effect->SetTechnique( hTechnique );
566                               
567                                effect->Begin( &nPasses, 0 );
568                                for(UINT j=0; j<nPasses; j++){
569                                        effect->BeginPass(j);
570                                        effect->SetTexture("rayOriginTable", rayOriginTableTexture);
571                                        effect->SetTexture("rayDirTable", rayDirTableTexture);
572                                        effect->SetTexture("conePeakTable", conePeakTexture);
573                                        effect->SetTexture("coneDirTable", coneDirTexture);
574                                        effect->CommitChanges();
575                                        drawFullScreenQuad(device);
576                                        effect->EndPass();
577                                }
578                                effect->End();
579                        }
580                        device->EndScene();
581                }
582/*/     
583                hr=device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
584                device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
585                device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
586                device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
587                device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
588                device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
589                hr=device->SetRenderState(D3DRS_STENCILMASK, 0x1 << rd);
590                hr=device->SetRenderState(D3DRS_STENCILWRITEMASK, 0x2 << rd);
591
592                hr=device->SetRenderTarget(1,rayDirTableSurface2);
593                hr=device->SetRenderTarget(0,rayOriginTableSurface2);
594                hr=device->SetDepthStencilSurface(depthSurface);
595
596                device->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
597                                                        D3DCOLOR_ARGB(1,0,0,0), 1.0f, 0 );
598
599                D3DLOCKED_RECT peakData;
600                hr = device->GetRenderTargetData(conePeakSurface, conePeakSurfaceMem);
601                hr =  conePeakSurfaceMem->LockRect(&peakData, NULL, D3DLOCK_READONLY);
602                float* conePeaks = (float*)peakData.pBits;
603
604                D3DLOCKED_RECT coneData;
605                hr = device->GetRenderTargetData(coneDirSurface, coneDirSurfaceMem);
606                hr =  coneDirSurfaceMem->LockRect(&coneData, NULL, D3DLOCK_READONLY);
607                float* coneDirs = (float*)coneData.pBits;
608
609                if( SUCCEEDED( device->BeginScene() ) ){
610                        if( effect != NULL ){
611                                D3DXHANDLE hTechnique = effect->GetTechniqueByName((LPSTR)"RayCast");
612                                if(hTechnique==NULL){
613                                        return;
614                                }
615                                effect->SetTechnique( hTechnique );
616                               
617                                effect->Begin( &nPasses, 0 );
618                                for(UINT j=0;j<nPasses;j++){
619                                        effect->BeginPass(j);
620                                        hr = effect->SetFloat("RefractionIndex", 0.9);
621                                        hr=effect->SetTexture("conePeakTable",conePeakTexture);
622                                        hr=effect->SetTexture("coneDirTable",coneDirTexture);
623                                        hr=effect->SetTexture("rayOriginTable",rayOriginTableTexture);
624                                        hr=effect->SetTexture("rayDirTable",rayDirTableTexture);
625                                        hr = device->SetVertexDeclaration(trianglePrimitiveDeclaration);
626
627                                        //loop through all entities, all mesh subsets, set proper transformations
628                                        std::vector<HREEffect::Entity>::iterator entityIterator = entities.begin();
629                                        while(entityIterator != entities.end())
630                                        {
631                                                hr = device->SetStreamSource(0, entityIterator->mesh->primitiveVertexBuffer, 0, sizeof(ProcessedTriangle));
632                                                hr=effect->SetMatrix("World", &entityIterator->modelWorldTransform);
633                                                hr=effect->SetMatrix("WorldIT", &entityIterator->inverseTransposedModelWorldTransform);
634                                                hr=effect->SetFloat("colOrder", 10.0f);
635
636                                                for(int cx=0; cx<32; cx++)
637                                                        for(int cy=0; cy<32; cy++)
638                                                        {
639                                                                Vector tilePos(-1.0 + 0.0625 * 0.5 + 0.0625*cx, -1.0 + 0.0625 * 0.5 + 0.0625*cy, 0.0);
640                                                                hr = effect->SetFloatArray("TilePos", (float*)&tilePos, 3);
641//                                                              D3DVECTOR worldConePeak = *(D3DVECTOR*)(conePeaks + cx * 4 + (31 - cy) * 32 * 4);
642//                                                              D3DVECTOR modelConePeak = worldConePeak * entityIterator->inverseTransposedModelWorldTransform;
643                                                                hr = effect->SetFloatArray("ConePeak",conePeaks + cx * 4 + (31 - cy) * 32 * 4 , 4);
644                                                                hr = effect->SetFloatArray("ConeDirAndCosAngle", coneDirs + cx * 4 + (31 - cy) * 32 * 4, 4);
645                                                                effect->CommitChanges();
646                                                                device->DrawPrimitive(D3DPT_POINTLIST, 0, entityIterator->mesh->mesh->GetNumFaces());
647                                                        }
648                                                entityIterator++;
649                                        }
650       
651                                        effect->EndPass();
652                                }
653                                effect->End();
654                        }
655                        device->EndScene();
656                }
657
658                conePeakSurfaceMem->UnlockRect();
659                coneDirSurfaceMem->UnlockRect();
660
661                hr=device->SetRenderState(D3DRS_STENCILMASK, 0x2 << rd);
662                hr=device->SetRenderState(D3DRS_STENCILWRITEMASK, 0x0);
663                hr=device->SetRenderTarget(1,rayDirTableSurface);
664                hr=device->SetRenderTarget(0,rayOriginTableSurface);
665
666                if( SUCCEEDED( device->BeginScene() ) ){
667                        if( effect != NULL ){
668                                D3DXHANDLE hTechnique = effect->GetTechniqueByName((LPSTR)"CopyBack");
669                                if(hTechnique==NULL){
670                                        return;
671                                }
672                                effect->SetTechnique( hTechnique );
673                               
674                                effect->Begin( &nPasses, 0 );
675                                for(UINT j=0;j<nPasses;j++){
676                                        effect->BeginPass(j);
677                                        hr=effect->SetTexture("rayOriginTable",rayOriginTableTexture2);
678                                        hr=effect->SetTexture("rayDirTable",rayDirTableTexture2);
679                                        effect->CommitChanges();
680                                        drawFullScreenQuad(device);
681                                        effect->EndPass();
682                                }
683                                effect->End();
684                        }
685                        device->EndScene();
686                }//*/
687        }
688
689        //eval directions, read from envmap
690        hr=device->SetRenderTarget(0,rayOriginTableSurface2);
691        hr=device->SetRenderTarget(1,NULL);
692
693        device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
694        device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
695        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
696        device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
697        device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
698
699        device->Clear( 0, NULL, D3DCLEAR_ZBUFFER,
700                                                D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
701
702        D3DXMATRIX screenToWorld;
703        D3DXMATRIX screenToWorldIT = *camera->GetViewMatrix() * *camera->GetProjMatrix();
704        D3DXMatrixInverse(&screenToWorld, NULL, &screenToWorldIT);
705        if( SUCCEEDED( device->BeginScene() ) ){
706                if( effect != NULL ){
707                        D3DXHANDLE hTechnique = effect->GetTechniqueByName((LPSTR)"Background");
708                        if(hTechnique==NULL){
709                                return;
710                        }
711                        effect->SetTechnique( hTechnique );
712                       
713                        effect->Begin( &nPasses, 0 );
714                        for(UINT j=0;j<nPasses;j++){
715                                effect->BeginPass(j);
716                                hr = effect->SetFloatArray("EyePos", (float*)&eyePos, 3);
717                                hr=effect->SetMatrix("ViewProjI", &screenToWorld);
718                                hr=effect->SetTexture("rayDirTable",rayDirTableTexture);
719                                hr=effect->SetTexture("environmentTexture",environmentCubeTexture);
720                                effect->CommitChanges();
721                                drawFullScreenQuad(device);
722                                effect->EndPass();
723                        }
724                        effect->End();
725                }
726                device->EndScene();
727        }
728
729        //render image
730        hr=device->SetDepthStencilSurface(frameDepthStencilBuffer);
731
732        hr=device->SetRenderTarget(1,NULL);
733        hr=device->SetRenderTarget(0, frameColorBuffer);
734        device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
735        device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
736
737        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
738
739        device->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
740                                D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
741
742        if( SUCCEEDED( device->BeginScene() ) ){
743                if( effect != NULL ){
744                        D3DXHANDLE hTechnique = effect->GetTechniqueByName((LPSTR)"ShowTex");
745                        if(hTechnique==NULL){
746                                return;
747                        }
748                        effect->SetTechnique( hTechnique );
749                       
750                        effect->Begin( &nPasses, 0 );
751                        for(UINT j=0;j<nPasses;j++){
752                                effect->BeginPass(j);
753                                hr=effect->SetTexture("coneDirTableSampler",coneDirTexture);
754                                hr=effect->SetTexture("conePeakTableSampler",coneDirTexture);
755                                hr=effect->SetTexture("rayOriginTable",rayOriginTableTexture2);
756                                hr=effect->SetTexture("rayDirTable",rayDirTableTexture);
757//                              hr=effect->SetTexture("rayOriginTable",rayOriginTableTexture);
758//                              hr=effect->SetTexture("rayDirTable",rayDirTableTexture);
759//                              hr=effect->SetTexture("rayDirTable",coneDirTexture);
760//                              hr=effect->SetTexture("rayOriginTable",conePeakTexture);
761                                effect->CommitChanges();
762                                drawFullScreenQuad(device);
763                                effect->EndPass();
764                        }
765                        effect->End();
766                }
767                device->EndScene();
768        }
769}
770
771void HREEffect::drawFullScreenQuad(LPDIRECT3DDEVICE9 device, float depth, float fLeftU, float fTopV, float fRightU, float fBottomV)
772{
773    D3DSURFACE_DESC dtdsdRT;
774    PDIRECT3DSURFACE9 pSurfRT;
775
776    // Acquire render target width and height
777    device->GetRenderTarget(0, &pSurfRT);
778    pSurfRT->GetDesc(&dtdsdRT);
779    pSurfRT->Release();
780
781    // Ensure that we're directly mapping texels to pixels by offset by 0.5
782    // For more info see the doc page titled "Directly Mapping Texels to Pixels"
783    FLOAT fWidth5 = (FLOAT)dtdsdRT.Width - 0.5f;
784    FLOAT fHeight5 = (FLOAT)dtdsdRT.Height - 0.5f;
785
786        struct D3DVERTEX{
787                D3DXVECTOR3 pos;
788                D3DXVECTOR2 tex0;
789        };
790
791    // Draw the quad
792    D3DVERTEX svQuad[4];
793
794    svQuad[0].pos=D3DXVECTOR3(-1, 1, depth);
795    svQuad[0].tex0 = D3DXVECTOR2(fLeftU, fTopV);
796
797    svQuad[1].pos = D3DXVECTOR3(1, 1, depth);
798    svQuad[1].tex0 = D3DXVECTOR2(fRightU, fTopV);
799
800    svQuad[2].pos = D3DXVECTOR3(-1, -1, depth);
801    svQuad[2].tex0 = D3DXVECTOR2(fLeftU, fBottomV);
802
803    svQuad[3].pos = D3DXVECTOR3(1, -1, depth);
804    svQuad[3].tex0 = D3DXVECTOR2(fRightU, fBottomV);
805       
806        device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
807        device->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
808    device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, svQuad, sizeof(D3DVERTEX));
809}
Note: See TracBrowser for help on using the repository browser.