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

Revision 896, 9.7 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                unsigned int            nSubsets;       //!< number of submeshes (with possible different material)
96                LPD3DXMESH                      mesh;           //!< D3D mesh
97                LPD3DXBUFFER            materialBuffer; //!< D3D material buffer
98                D3DXMATERIAL*           materials;              //!< D3D material array
99                LPDIRECT3DTEXTURE9*     textures;               //!< D3D textures for the materials
100                Material*                       rayTraceMaterial;       //!< material used in for ray tracing
101                TriangleMesh*           rayTraceMesh;           //!< the raytracable representation of the mesh
102                LPDIRECT3DVERTEXBUFFER9 edgeVertexBuffer;       //!< a set of line primitives for atlas (PRM) rendering
103                int                                     nEdges;                                 //!< number of line primitives in edgeVertexBuffer
104
105                HRESULT setVertexFormat(DWORD fvf, LPDIRECT3DDEVICE9 device);   //!< rebuild D3D to have differnet vertex format
106                void buildEdgeVertexBuffer(LPDIRECT3DDEVICE9 device);                   //!< compute line primitives to edgeVertexBuffer
107        };
108
109        //! vector of loaded meshes
110        std::vector<RenderMesh*>        renderMeshes;
111        //! vector of loaded textures (textures specified in mesh's material will be loaded here)
112        std::vector<LPDIRECT3DTEXTURE9> materialTextures;
113
114        //! for materials with no texture we will render with this texture
115        LPDIRECT3DTEXTURE9              emptyTexture;
116
117        //! private method that loads a mesh and its textures
118        void loadMesh(LPCWSTR fileName);
119
120        //! private method to load a texture
121        LPDIRECT3DTEXTURE9 loadTexture(LPCWSTR fileName);
122
123        //! release material texture resources
124        void releaseTextures();
125        //! release mesh resources
126        void releaseMeshes();
127        //! release entities
128        void releaseEntities();
129
130        //! struct that represents a virtual world object: a mesh and a model-world transformation matrix
131        friend struct Entity;
132        struct Entity
133        {
134                PathMapEffect* owner;   //!< enclosing class instance
135
136                RenderMesh*     renderMesh;             //!< mesh
137                Transformed* rayTraceEntity;    //!< raytracable entity containing the mesh's TriangleMesh
138                D3DXMATRIX      modelWorldTransform;    //!< modeling transform
139                D3DXMATRIX      inverseTransposedModelWorldTransform;   //!< IT modeling transform for surface normal transformation
140               
141                LPDIRECT3DTEXTURE9 prmTexture;          //!< a collection of tiled texture atlases containing illuminaton contributions of nearest entry point clusters
142                LPDIRECT3DSURFACE9 prmSurface;          //!< prmTexture's surface
143
144                void createRayTraceEntity();            //!< setup rayTraceEntity
145
146                //! render contributions of virtual light sources in 'bushRadions' to atlas corresponding to cluster 'bushId'
147                void renderPRM(LPDIRECT3DDEVICE9 device,
148                                                        LPD3DXEFFECT effect,
149                                                        std::vector<Radion>& bushRadions,
150                                                        unsigned int bushId,
151                                                        float scaleFactor);
152
153                //! array of cluster indices storing which clusters are relevant. PRM tiles correspond to these clusters
154                unsigned int nearClusterIndices[NCLUSTERSPERENTITY];
155
156                //! fill the nearClusterIndices array
157                void findNearClusters(const std::vector<Radion>& starters, unsigned int nClusters);
158               
159        };
160
161        //! renders a full screen quad, invoking the pixel shader for all pixels
162        //! used for rendering the environment map to the background
163        void renderFullScreen(float depth = 0.0f);
164
165        //! vector of virtual world objects
166        std::vector<Entity> entities;
167public:
168        //! constructor: allocates all resources
169        PathMapEffect(LPDIRECT3DDEVICE9 device);
170        //! destructor: releases all resources
171        ~PathMapEffect(void);
172
173        //! renders the scene using the currently selected method
174        void render();
175
176        //! renders the scene, usings the PRMs for indirect illumination
177        void renderWithPRM();
178
179        //! displays a part of a PRM texture
180        void showPRMTexture();
181
182        //! moves the virtual world objects (camera, light)
183        void move(float fElapsedTime);
184
185        LRESULT handleMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
186
187        //! adds controls for the user-adjustable application parameters
188        static void addUiParameters(Parameters* parameters);
189        static void setUiParameterDefaults(Parameters* parameters);
190
191        LPDIRECT3DDEVICE9 getDevice() {return device;}
192
193        const wchar_t* getWeightsString();
194private:
195        float weights[NCLUSTERS];                               //!< the array of averaged cluster weights
196        unsigned int clusterLenghts[NCLUSTERS]; //!< array thet contasins the number of entry points in every cluster (entry points are stored continously [bushStarters, starterVertexBuffer])
197
198        float sumSurfaceArea;                                   //!< summed surface area of all entities
199
200        void createPRMTextures();                               //!< allocates PRM resources for every entity
201
202        //! generates a random direction (cosine distribution) near a normal vector
203        static void sampleShootingDiffuseDirection(int depth, const Vector& normal, Vector& outDir);
204        //! generates a random direction an the unit sphere
205        static void sampleSphereDirection(Vector& outDir);
206       
207        //! finds a random entry point (all entities considered with equal probability)
208        void sampleSurfaceRadion(Radion& starter);
209        //! finds a random entry point (all entities considered with probability proporstional to surface area)
210        void sampleSurfaceRadionUniform(Radion& starter);
211
212        //! shoot virtual light sources from original entry point and add them to the vector
213        void shootRadionBush(Radion& starter, std::vector<Radion>& bushRadions);
214
215        //! sort radions into initial, uniform length clusters
216        int clusterRadions(Radion* partition, int psize, char axis);
217
218        //! use K-means clustering to cluster radions
219        void clusterRadionsKMeans();
220
221        //! perform computaions: generate entry points, render PRMs
222        void precompute();
223
224        int getNBushes() {return NRADIONS; }
225        int getNClusters() {return NCLUSTERS;}
226
227        //! entry points
228        std::vector<Radion> bushStarters;
229
230        int rayId;
231        Ray ray;
232        HitRec hitRec;
233
234        //! render a full-screen quad
235        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);
236
237        //! fill 'radionsTexture' from 'bushStarters'
238        void uploadRadions();
239        //! fill *pData (will point to locked 'starterVertexBuffer') from 'bushStarters'
240        void fillRadionPosArray(void* pData);
241
242public:
243        //! store all precomputed data for the scene in folder prm
244        void savePathMaps();
245        //! restore all precomputed data for the scene from folder prm
246        void loadPathMaps();
247};
Note: See TracBrowser for help on using the repository browser.