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 |
|
---|
18 | class Material;
|
---|
19 | class TriangleMesh;
|
---|
20 | class Transformed;
|
---|
21 | class KDTree;
|
---|
22 |
|
---|
23 | /*!
|
---|
24 | \brief Main class for the PRM computation and usage application.
|
---|
25 | This class encapsulates all resources needed for computing PRMs and
|
---|
26 | using them in the final rendering. PRM resources may be generated,
|
---|
27 | saved to files, or restored.
|
---|
28 | */
|
---|
29 | class 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;
|
---|
81 | public:
|
---|
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;
|
---|
90 | private:
|
---|
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;
|
---|
174 | public:
|
---|
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();
|
---|
201 | private:
|
---|
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 |
|
---|
249 | public:
|
---|
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 | };
|
---|