source: GTP/trunk/App/Demos/Illum/PathMap/PathMapEffect.h @ 1480

Revision 1480, 9.9 KB checked in by szirmay, 18 years ago (diff)
Line 
1#pragma once
2#include <vector>
3#include "Parameters.h"
4#include "Vector.hpp"
5#include "Uniform.hpp"
6#include "Radion.hpp"
7#include "KDTree.hpp"
8
9#define ATLASSIZE 128
10#define DBLATLASSIZE (ATLASSIZE * 2.0)
11
12#define NRADIONS                (4096)
13#define NCLUSTERS       32
14#define DEPTHMAPRES     512
15#define NCLUSTERSPERENTITY 32
16
17
18class Material;
19class TriangleMesh;
20class Transformed;
21class KDTree;
22
23/*!
24\brief Main class for the PRM computation and usage application.
25This class encapsulates all resources needed for computing PRMs and
26using them in the final rendering. PRM resources may be generated,
27saved to files, or restored.
28*/
29class PathMapEffect
30{
31        //! pointer to global user-adjustable application parameters object
32        static Parameters*              parameters;
33
34        //! pointer to main DX device
35        LPDIRECT3DDEVICE9               device;
36        //! pointer to main DX effect
37        LPD3DXEFFECT                    effect;
38
39        //! frame color buffer surface
40        //! saved before render-to-texture, and restored as the render target for the final rendering to the screen
41        LPDIRECT3DSURFACE9              frameColorBuffer;
42        //! frame depth buffer surface
43        //! saved before render-to-texture, and restored as the render target for the final rendering to the screen
44        LPDIRECT3DSURFACE9              frameDepthStencilBuffer;
45
46        LPDIRECT3DTEXTURE9              depthMapTexture;                                //!< depth map texture
47        LPDIRECT3DSURFACE9              depthMapDepthStencilBuffer;             //!< depth map texture's surface
48        LPDIRECT3DTEXTURE9              fakeTexture;                                    //!< depth map dummy render texture
49        LPDIRECT3DSURFACE9              fakeSurface;                                    //!< depth map dummy render surface
50
51        LPDIRECT3DSURFACE9              prmBlendingDepthStencilBuffer;  //!< stencil buffer for rendering a virtual light source to the PRM
52
53        LPDIRECT3DVERTEXBUFFER9 starterVertexBuffer;                    //!< vertex buffer with entry point positions, for entry point visualization
54
55        LPDIRECT3DTEXTURE9              weightsTexture;                                 //!< render target texture to which current entry point weights are computed
56        LPDIRECT3DSURFACE9              weightsSurface;                                 //!< weights texture's surface
57    LPDIRECT3DTEXTURE9  sysMemWeightsTexture;                           //!< weights texture copy in system mem
58    LPDIRECT3DSURFACE9  sysMemWeightsSurface;                           //!< surface of weights texture copy in system mem
59        LPDIRECT3DTEXTURE9              radionTexture;                                  //!< texture containing entry point data, input for weight computation
60        LPDIRECT3DSURFACE9              radionSurface;                                  //!< entry point texture's surface
61
62        KDTree* kdtree;         //!< the kd-tree that contains the scene geometry in raytraceable format
63
64        //! clever enum for supported final rendering methods
65        class Method{
66                unsigned int mid;
67                Method(unsigned int mid) {this->mid = mid;}
68                static const wchar_t * methodNames[10];
69        public:
70                Method(const Method& o) {mid = o.mid;}
71                const Method& operator=(const Method& o) {mid = o.mid; return *this;}
72                bool operator==(const Method& o) const {return mid == o.mid;}
73                bool operator!=(const Method& o) const {return mid != o.mid;}
74                const static Method PRM;
75                const static Method SHOWTEX;
76                const static Method LAST;
77                const Method& next() {mid = (mid + 1)%LAST.mid; return *this;}
78                const Method& prev() {mid = (mid + LAST.mid - 1)%LAST.mid; return *this;}
79                const wchar_t* getName() {return methodNames[mid];}
80        }method;
81public:
82        void nextMethod() {method.next();}
83        void prevMethod() {method.prev();}
84        const wchar_t* getCurrentMethodName() {return method.getName();}
85
86        //! camera
87        CFirstPersonCamera*                     camera;
88        //! primary light source (can be moved just like the real camera, and can be used as the camera)
89        CFirstPersonCamera*                     lightCamera;
90private:
91
92        //! struct containing all mesh related data. Will be filled from X files in PathMapEffect constructor
93        struct RenderMesh
94        {
95                char                            name[256];
96
97                unsigned int            nSubsets;       //!< number of submeshes (with possible different material)
98                LPD3DXMESH                      mesh;           //!< D3D mesh
99                LPD3DXBUFFER            materialBuffer; //!< D3D material buffer
100                D3DXMATERIAL*           materials;              //!< D3D material array
101                LPDIRECT3DTEXTURE9*     textures;               //!< D3D textures for the materials
102                Material*                       rayTraceMaterial;       //!< material used in for ray tracing
103                TriangleMesh*           rayTraceMesh;           //!< the raytracable representation of the mesh
104                LPDIRECT3DVERTEXBUFFER9 edgeVertexBuffer;       //!< a set of line primitives for atlas (PRM) rendering
105                int                                     nEdges;                                 //!< number of line primitives in edgeVertexBuffer
106
107                HRESULT setVertexFormat(DWORD fvf, LPDIRECT3DDEVICE9 device);   //!< rebuild D3D to have differnet vertex format
108                void buildEdgeVertexBuffer(LPDIRECT3DDEVICE9 device);                   //!< compute line primitives to edgeVertexBuffer
109        };
110
111        //! vector of loaded meshes
112        std::vector<RenderMesh*>        renderMeshes;
113        //! vector of loaded textures (textures specified in mesh's material will be loaded here)
114        std::vector<LPDIRECT3DTEXTURE9> materialTextures;
115
116        //! for materials with no texture we will render with this texture
117        LPDIRECT3DTEXTURE9              emptyTexture;
118
119        //! private method that loads a mesh and its textures
120        void loadMesh(LPCWSTR fileName);
121
122        //! private method to load a texture
123        LPDIRECT3DTEXTURE9 loadTexture(LPCWSTR fileName);
124
125        //! release material texture resources
126        void releaseTextures();
127        //! release mesh resources
128        void releaseMeshes();
129        //! release entities
130        void releaseEntities();
131
132        //! struct that represents a virtual world object: a mesh and a model-world transformation matrix
133        friend struct Entity;
134        struct Entity
135        {
136                char                            name[256];
137                char                            prmfilename[256];
138                int                                     nNearClusters;
139                int                                     rpmAtlasSize;
140
141                PathMapEffect* owner;   //!< enclosing class instance
142
143                RenderMesh*     renderMesh;             //!< mesh
144                Transformed* rayTraceEntity;    //!< raytracable entity containing the mesh's TriangleMesh
145                D3DXMATRIX      modelWorldTransform;    //!< modeling transform
146                D3DXMATRIX      inverseTransposedModelWorldTransform;   //!< IT modeling transform for surface normal transformation
147               
148                LPDIRECT3DTEXTURE9 prmTexture;          //!< a collection of tiled texture atlases containing illuminaton contributions of nearest entry point clusters
149                LPDIRECT3DSURFACE9 prmSurface;          //!< prmTexture's surface
150
151                void createRayTraceEntity();            //!< setup rayTraceEntity
152
153                //! render contributions of virtual light sources in 'bushRadions' to atlas corresponding to cluster 'bushId'
154                void renderPRM(LPDIRECT3DDEVICE9 device,
155                                                        LPD3DXEFFECT effect,
156                                                        std::vector<Radion>& bushRadions,
157                                                        unsigned int bushId,
158                                                        float scaleFactor);
159
160                //! array of cluster indices storing which clusters are relevant. PRM tiles correspond to these clusters
161                unsigned int nearClusterIndices[32];
162
163                //! fill the nearClusterIndices array
164                void findNearClusters(const std::vector<Radion>& starters, unsigned int nClusters);
165               
166        };
167
168        //! renders a full screen quad, invoking the pixel shader for all pixels
169        //! used for rendering the environment map to the background
170        void renderFullScreen(float depth = 0.0f);
171
172        //! vector of virtual world objects
173        std::vector<Entity> entities;
174public:
175        //! constructor: allocates all resources
176        PathMapEffect(LPDIRECT3DDEVICE9 device);
177        //! destructor: releases all resources
178        ~PathMapEffect(void);
179
180        //! renders the scene using the currently selected method
181        void render();
182
183        //! renders the scene, usings the PRMs for indirect illumination
184        void renderWithPRM();
185
186        //! displays a part of a PRM texture
187        void showPRMTexture();
188
189        //! moves the virtual world objects (camera, light)
190        void move(float fElapsedTime);
191
192        LRESULT handleMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
193
194        //! adds controls for the user-adjustable application parameters
195        static void addUiParameters(Parameters* parameters);
196        static void setUiParameterDefaults(Parameters* parameters);
197
198        LPDIRECT3DDEVICE9 getDevice() {return device;}
199
200        const wchar_t* getWeightsString();
201private:
202        float weights[NCLUSTERS];                               //!< the array of averaged cluster weights
203        unsigned int clusterLenghts[NCLUSTERS]; //!< array thet contasins the number of entry points in every cluster (entry points are stored continously [bushStarters, starterVertexBuffer])
204
205        float sumSurfaceArea;                                   //!< summed surface area of all entities
206
207        void createPRMTextures();                               //!< allocates PRM resources for every entity
208
209        //! generates a random direction (cosine distribution) near a normal vector
210        static void sampleShootingDiffuseDirection(int depth, const Vector& normal, Vector& outDir);
211        //! generates a random direction an the unit sphere
212        static void sampleSphereDirection(Vector& outDir);
213       
214        //! finds a random entry point (all entities considered with equal probability)
215        void sampleSurfaceRadion(Radion& starter);
216        //! finds a random entry point (all entities considered with probability proporstional to surface area)
217        void sampleSurfaceRadionUniform(Radion& starter);
218
219        //! shoot virtual light sources from original entry point and add them to the vector
220        void shootRadionBush(Radion& starter, std::vector<Radion>& bushRadions);
221
222        //! sort radions into initial, uniform length clusters
223        int clusterRadions(Radion* partition, int psize, char axis);
224
225        //! use K-means clustering to cluster radions
226        void clusterRadionsKMeans();
227
228        //! perform computaions: generate entry points, render PRMs
229        void precompute();
230
231        int getNBushes() {return NRADIONS; }
232        int getNClusters() {return NCLUSTERS;}
233
234        //! entry points
235        std::vector<Radion> bushStarters;
236
237        int rayId;
238        Ray ray;
239        HitRec hitRec;
240
241        //! render a full-screen quad
242        static void drawFullScreenQuad(LPDIRECT3DDEVICE9 device, float depth = 0.0f, float fLeftU=0.0f, float fTopV=0.0f, float fRightU=1.0f, float fBottomV=1.0f);
243
244        //! fill 'radionsTexture' from 'bushStarters'
245        void uploadRadions();
246        //! fill *pData (will point to locked 'starterVertexBuffer') from 'bushStarters'
247        void fillRadionPosArray(void* pData);
248
249public:
250        //! store all precomputed data for the scene in folder prm
251        void savePathMaps();
252        //! restore all precomputed data for the scene from folder prm
253        void loadPathMaps();
254
255        void exportEntityData();
256
257        void loadScene(const char* sceneFileName);
258};
Note: See TracBrowser for help on using the repository browser.